package cn.lan.generator.manager;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.lan.generator.dao.BaseDao;
import cn.lan.generator.bean.TableEntity;
import cn.lan.generator.bean.Connector;
import cn.lan.generator.bean.ProjInfo;
import cn.lan.generator.factory.TableInfoFactory;
import cn.lan.generator.service.CreatePublicFile;
import cn.lan.generator.service.CreatePomXml;
import cn.lan.generator.service.impl.CreatePublicFileImpl;
import cn.lan.generator.service.impl.CreatePomXmlFileImpl;
import cn.lan.generator.utils.FileUtil;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * 自动生成项目文件
 *
 * @author 兰平
 * @version 1.5
 * @date 2017-7-16
 */
public class MySQLProjectManager extends AbstractProjectManager {

    @Override
    public void createFilesEmptyBusiness(Connector connector, ProjInfo projInfo) throws Exception {
        CreatePublicFile createPublicFile = new CreatePublicFileImpl();
        createPublicFile.writeFile(projInfo,connector);

        FileUtil.finishWrite(projInfo);
    }

    /**
     * 创建web项目相关文件
     *
     * @throws Exception
     */
    @Override
    public void createFiles(Connector connector, ProjInfo projInfo) throws Exception {
        createFiles(connector,projInfo,true);
    }

    @Override
    public void createFiles(Connector connector, ProjInfo projInfo, boolean hasCommon) throws Exception {
        createFilesAllTables(connector,projInfo);
        if(hasCommon){
            createFilesEmptyBusiness(connector,projInfo);
            return;
        }
        FileUtil.finishWrite(projInfo);
    }

    /**
     * 创建所有表文件
     * @param connector
     * @param projInfo
     * @throws Exception
     */
    private void createFilesAllTables(Connector connector, ProjInfo projInfo) throws Exception{
        BaseDao baseDao = new BaseDao(connector);
        Connection con = baseDao.getConnection();
        ResultSet rs = null;
        PreparedStatement pstmt = null;
        try {
            if (con == null) {
                System.out.println("数据库连接失败");
                return;
            }
            String schema = con.getCatalog();
            System.out.println("数据库名：" + schema);
            DatabaseMetaData dmd = con.getMetaData();
            rs = dmd.getTables(schema, schema, "%", null);
            while (rs.next()) {
                String tableName = rs.getString("TABLE_NAME");
                System.out.println("数据库表[" + tableName + "]");
                //查询表注释
                String tableComment = TableInfoFactory.getTableService(connector.getDbType()).getTableComment(con, schema, tableName);
                if("VIEW".equals(tableComment) || "SYSTEM VIEW".equals(tableName)){
                    //跳过视图
                    continue;
                }
                String sql = "select * from information_schema.columns where " +
                        " table_schema = '" + schema + "' and table_name = '" + tableName + "' ORDER BY ORDINAL_POSITION ";
                pstmt = con.prepareStatement(sql);
                ResultSet result = pstmt.executeQuery();

                EntityRelationManager entityRelationManager = new EntityRelationManager();
                entityRelationManager.createEntityBusiFile(projInfo, tableName, tableComment, result, connector.getDbType(), connector.getSchema());
            }

        } finally {
            baseDao.closeAll(con, pstmt, rs);
        }
    }

    /**
     * 单张表对应的项目文件
     */
    private void createFilesByOneTable(Connector connector, ProjInfo projInfo,String tableName,String tableComment) throws Exception {
        BaseDao baseDao = new BaseDao(connector);
        Connection con = baseDao.getConnection();
        ResultSet rs = null;
        PreparedStatement pstmt = null;
        try {
            if (con == null) {
                System.out.println("数据库连接失败");
                return;
            }
            String schema = con.getCatalog();
            System.out.println("数据库表[" + tableName+ "]");

            if(StrUtil.isBlank(tableComment)){
                tableComment = TableInfoFactory.getTableService(connector.getDbType()).getTableComment(con,schema,tableName);
            }

            String sql = "select * from information_schema.columns where " +
                    " table_schema = '" + schema + "' and table_name = '" + tableName + "' ORDER BY ORDINAL_POSITION ";
            pstmt = con.prepareStatement(sql);
            ResultSet result = pstmt.executeQuery();

            EntityRelationManager entityRelationManager = new EntityRelationManager();
            entityRelationManager.createEntityBusiFile(projInfo,tableName,tableComment,result,connector.getDbType(),connector.getSchema());

        } finally {
            baseDao.closeAll(con, pstmt, rs);
        }
    }

    @Override
    public void createFilesByTables(Connector connector, ProjInfo projInfo, TableEntity tableEntity) throws Exception {
        if(ObjectUtil.isEmpty(tableEntity.getTableNames())){
            throw new Exception("tableEntity.tableNames must not be null");
        }

        for(int i=0;i<tableEntity.getTableNames().length;i++){
            String tableComment = "";
            if(tableEntity.getTableComments()!=null
                && tableEntity.getTableComments().length>i){
                tableComment = tableEntity.getTableComments()[i];
            }
            createFilesByOneTable(connector,projInfo,tableEntity.getTableNames()[i],tableComment);
        }
        if(projInfo.isCreateModulePomXml()){
            CreatePomXml createPomXml = new CreatePomXmlFileImpl();
            createPomXml.writeFile(projInfo);
        }

        FileUtil.finishWrite(projInfo);
    }
}
